package com.fitns.user.service.user;

import com.fitns.user.constant.Constants;
import com.fitns.user.constant.RedisKey;
import com.fitns.user.dao.user.UserDao;
import com.fitns.user.dto.user.LoginVO;
import com.fitns.user.dto.user.UserVO;
import com.fitns.user.exception.LoginMsgCode;
import com.fitns.user.exception.ServiceException;
import com.fitns.user.exception.UserMsgCode;
import com.fitns.user.model.user.User;
import com.fitns.user.utils.ContextUtils;
import com.fitns.user.utils.DeEnCode;
import com.fitns.user.utils.RedisUtil;
import com.xiaoleilu.hutool.crypto.SecureUtil;
import com.xiaoleilu.hutool.lang.Validator;
import com.xiaoleilu.hutool.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 *
 * Created by zhou  on 2018/08/01
 *
 */

@Service
@Slf4j
public class LoginService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisUtil redisUtil;

    private static final int smsCodeLength=4;

    public UserVO login(LoginVO loginVO){
        this.validateLogin(loginVO);
        //查找用户是否存在
        //加密
        String SecUser=DeEnCode.encode(loginVO.getNameOrTell());
        User user= userDao.findUserByTellOrName(SecUser);
        if(Validator.isNull(user)){
            throw ServiceException.create(LoginMsgCode.USER_NOT_FIOUND);
        }
        // 校验用户密码是否正确
        String rsaPassword  =DeEnCode.encode(loginVO.getPassword());
        if (!rsaPassword.equals(user.getPassword())) {
            throw ServiceException.create(LoginMsgCode.USER_PASSWORD_ERROR);
        }
        if(Validator.isNull(user.getOrganId())){
            throw ServiceException.create(UserMsgCode.USER_ORGAN_IS_NULL);
        }

        this.checkUser(user);
        UserVO userVO=userService.findDetailUser(user.getId());
        userVO.setToken(ContextUtils.getToken());

        //TODO 验证用户是否存在角色
        if(Validator.isNull(userVO.getRoleVOS())){
            throw ServiceException.create(UserMsgCode.USER_NO_ROLE_FOUND);
        }


        //验证是否第一次登录
        if(user.getLoginNum()==0){
            userVO.setFirstLogin(true);
        }else {
            userVO.setFirstLogin(false);
        }

        userVO.setLoginNum(user.getLoginNum()+1);
        userDao.update(userVO);


        //将用户信息放入缓存
        redisUtil.setex(RedisKey.USER_ID.of(userVO.getToken()),user.getId().toString());
        redisUtil.setex(RedisKey.USER.of(user.getId().toString()),userVO);


        return userService.deCodeUser(userVO);
    }





    public void checkUser(User user){
        if(Constants.IS_BLNVALID.NO==user.getBlnValid()){
            throw ServiceException.create(UserMsgCode.USER_NOT_BINVALID);
        }

    }

    public void validateLogin(LoginVO loginVO) {
        if (Validator.isNull(loginVO) || Validator.isNull(loginVO.getNameOrTell())) {
            throw ServiceException.create(LoginMsgCode.LOGIN_VO_IS_NULL);
        }
    }

    //发送验证码
    public String sendValidateCode(LoginVO loginVO){
        userService.validateMobileNo(loginVO.getMobileNo());

        User user= userService.findUserByTell(DeEnCode.encode(loginVO.getMobileNo()));
        if(Validator.isNull(user)){
            throw ServiceException.create(UserMsgCode.USER_NOT_EXIST);
        }
        // 生成验证码序列号
        String msgCode = RandomUtil.randomNumbers(smsCodeLength);
        // 缓存手机号码、验证码
        redisUtil.setex(RedisKey.VALIDATE_CODE.of(loginVO.getMobileNo()), SecureUtil.md5(msgCode),redisUtil.getShortTime());
       String code=RedisKey.VALIDATE_CODE.of(loginVO.getMobileNo());
        // 发送短信,验证码
        // TODO 发送短信
        log.info("给手机号:" + loginVO.getMobileNo() + ",发送短信验证码:" + msgCode);
        // 发送成功后,返回序列号
        // TODO 调试阶段直接返回短信验证码
        return msgCode;
    }

    //忘记密码
    public UserVO forgetPassword(LoginVO loginVO){
        userService.validateMobileNo(loginVO.getMobileNo());
        userService.validatePassword(loginVO.getPassword());
        String validateCode=redisUtil.get(RedisKey.VALIDATE_CODE.of(loginVO.getMobileNo()));
        if(Validator.isNull(validateCode)){
            throw ServiceException.create(LoginMsgCode.LOGIN_SEND_VALIDATE_CODE);
        }
        if(Validator.isNull(loginVO.getValidateCode())){
            throw ServiceException.create(LoginMsgCode.LOGIN_VALIDATE_CODE_IS_NULL);
        }

        if(!validateCode.equals(SecureUtil.md5(loginVO.getValidateCode()))){
            throw ServiceException.create(LoginMsgCode.LOGIN_VALIDATE_CODE_IS_ERROR);
        }

        User user=userDao.findUserByTellOrName(DeEnCode.encode(loginVO.getMobileNo()));
        if(Validator.isNull(user)){
            throw ServiceException.create(UserMsgCode.USER_NOT_EXIST);
        }
        user.setPassword(DeEnCode.encode(loginVO.getPassword()));
        UserVO userVO=new UserVO();
        BeanUtils.copyProperties(user,userVO);
        userDao.update(userVO);
        return userService.deCodeUser(userVO);
    }

    /**
     *
     * 功能描述: 退出登录
     *
     * @param:
     * @return:
     */
    public void loginOut(){
        String key=RedisKey.USER_ID.of(ContextUtils.getToken());
        redisUtil.delete(key);
    }



}
